package com.bbm.communitysystem.core;


import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.bbm.communitysystem.domain.dto.UserCredDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;

@Slf4j
@Component
public class Token {

    @Value("${token.secret}")
    private String secret;

    @Value("${token.expire}")
    private long expire;

    @Value("${token.threshold}")
    private long threshold;

    public String CreateToken(UserCredDto userCredDto) {
        return generate(userCredDto);
    }

    private String generate(UserCredDto userCredDto) {
        if (userCredDto == null) {
            return null;
        }

        return  JWT.create().addHeaders(InitHead())
                .addPayloads(InitPayload(userCredDto))
                .setSubject("单点登录")
                .setKey(secret.getBytes())
                .setExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 60 * expire))
                .sign();
    }

    private HashMap<String, Object> InitHead() {
        HashMap<String, Object> head = new HashMap<>();
        head.put("alg", "HS256");
        head.put("typ", "JWT");
        return head;
    }

    private HashMap<String, Object> InitPayload (UserCredDto userCredDto) {
        HashMap<String, Object> payload = new HashMap<>();
        payload.put("userId", userCredDto.getId());
        payload.put("time", new Date(System.currentTimeMillis() + 1000 * 60 * expire));
        return payload;
    }

    public int verify(String token) {
        if (token == null) {
            log.info("token为空");
            return 0;
        }

        long old = Long.parseLong(JWT.of(token).setKey(secret.getBytes()).getPayloads().get("time").toString());

        long now = System.currentTimeMillis();

        if (now - old < 0) {
            log.info("token已过期");
            return 0;
        }

        if (now - old > threshold * 60 * 1000) {
            log.info("token即将过期");
            return 2;
        }


        return 1;
    }

    public UserCredDto parseToken(String token) {
        if (verify(token) == 0) {
            log.info("token已过期");
            return null;
        }

        UserCredDto userCredDto = new UserCredDto();
        String string = JWTUtil.parseToken(token).getPayload("userId") + "";

        userCredDto.setId(Integer.valueOf(string));

        return userCredDto;
    }

    public String flushToken(String token) {
        return generate(parseToken(token));
    }

}
